package com.example.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.entity.CardInfo;
import com.example.entity.TradeInfo;
import com.example.mapper.CardInfoMapper;
import com.example.mapper.TradeInfoMapper;
import com.example.service.CardInfoService;
import com.example.utils.Result;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;

/**
 * 银行卡信息服务实现类
 */
@Service
public class CardInfoServiceImpl extends ServiceImpl<CardInfoMapper, CardInfo> implements CardInfoService {

    @Autowired
    private TradeInfoMapper tradeInfoMapper;

    /**
     * 存款
     */
    @Override
    @Transactional
    public Result<?> deposit(String cardId, BigDecimal amount) {
        // 验证参数
        if (amount.compareTo(BigDecimal.ZERO) <= 0) {
            return Result.error("存款金额必须大于0");
        }
        
        // 查询银行卡
        CardInfo cardInfo = getById(cardId);
        if (cardInfo == null) {
            return Result.error("银行卡不存在");
        }
        
        // 检查是否挂失
        if ("YES".equals(cardInfo.getIsReportLoss())) {
            return Result.error("该卡已挂失，无法进行存款操作");
        }
        
        // 更新余额
        cardInfo.setBalance(cardInfo.getBalance().add(amount));
        updateById(cardInfo);
        
        // 记录交易
        TradeInfo tradeInfo = new TradeInfo();
        tradeInfo.setCardId(cardId);
        tradeInfo.setTradeType("存款");
        tradeInfo.setTradeMoney(amount);
        tradeInfo.setRemark("存款操作");
        tradeInfoMapper.insert(tradeInfo);
        
        // 返回结果
        Map<String, Object> data = new HashMap<>();
        data.put("balance", cardInfo.getBalance());
        return Result.success("存款成功", data);
    }

    /**
     * 取款
     */
    @Override
    @Transactional
    public Result<?> withdraw(String cardId, BigDecimal amount, String password) {
        // 验证参数
        if (amount.compareTo(BigDecimal.ZERO) <= 0) {
            return Result.error("取款金额必须大于0");
        }
        
        // 查询银行卡
        CardInfo cardInfo = getById(cardId);
        if (cardInfo == null) {
            return Result.error("银行卡不存在");
        }
        
        // 检查是否挂失
        if ("YES".equals(cardInfo.getIsReportLoss())) {
            return Result.error("该卡已挂失，无法进行取款操作");
        }
        
        // 验证密码
        if (!cardInfo.getPass().equals(password)) {
            return Result.error("密码错误");
        }
        
        // 检查余额
        if (cardInfo.getBalance().compareTo(amount) < 0) {
            return Result.error("余额不足");
        }
        
        // 更新余额
        cardInfo.setBalance(cardInfo.getBalance().subtract(amount));
        updateById(cardInfo);
        
        // 记录交易
        TradeInfo tradeInfo = new TradeInfo();
        tradeInfo.setCardId(cardId);
        tradeInfo.setTradeType("取款");
        tradeInfo.setTradeMoney(amount);
        tradeInfo.setRemark("取款操作");
        tradeInfoMapper.insert(tradeInfo);
        
        // 返回结果
        Map<String, Object> data = new HashMap<>();
        data.put("balance", cardInfo.getBalance());
        return Result.success("取款成功", data);
    }

    /**
     * 转账
     */
    @Override
    @Transactional
    public Result<?> transfer(String fromCardId, String toCardId, BigDecimal amount, String password) {
        // 验证参数
        if (amount.compareTo(BigDecimal.ZERO) <= 0) {
            return Result.error("转账金额必须大于0");
        }
        
        // 准备输出参数Map
        Map<String, Object> paramMap = new HashMap<>();
        
        // 调用存储过程进行转账
        getBaseMapper().transfer(fromCardId, toCardId, amount.toString(), password, paramMap);
        
        // 获取输出参数
        Integer status = (Integer) paramMap.get("status");
        String message = (String) paramMap.get("message");
        
        if (status != null && status == 1) {
            return Result.success("转账成功");
        } else {
            return Result.error(message != null && !message.isEmpty() ? message : "转账失败");
        }
    }

    /**
     * 修改密码
     */
    @Override
    @Transactional
    public Result<?> changePassword(String cardId, String oldPassword, String newPassword) {
        // 查询银行卡
        CardInfo cardInfo = getById(cardId);
        if (cardInfo == null) {
            return Result.error("银行卡不存在");
        }
        
        // 验证旧密码
        if (!cardInfo.getPass().equals(oldPassword)) {
            return Result.error("原密码错误");
        }
        
        // 修改密码
        cardInfo.setPass(newPassword);
        updateById(cardInfo);
        
        return Result.success("密码修改成功");
    }

    /**
     * 挂失
     */
    @Override
    @Transactional
    public Result<?> reportLoss(String cardId) {
        // 查询银行卡
        CardInfo cardInfo = getById(cardId);
        if (cardInfo == null) {
            return Result.error("银行卡不存在");
        }
        
        // 设置挂失状态
        cardInfo.setIsReportLoss("YES");
        updateById(cardInfo);
        
        return Result.success("挂失成功");
    }

    /**
     * 解除挂失
     */
    @Override
    @Transactional
    public Result<?> cancelLoss(String cardId) {
        // 查询银行卡
        CardInfo cardInfo = getById(cardId);
        if (cardInfo == null) {
            return Result.error("银行卡不存在");
        }
        
        // 解除挂失状态
        cardInfo.setIsReportLoss("NO");
        updateById(cardInfo);
        
        return Result.success("解除挂失成功");
    }

    @Override
    @Transactional
    public boolean removeById(Serializable cardId) {
        // 先删除该银行卡的所有交易记录
        tradeInfoMapper.delete(
            new QueryWrapper<TradeInfo>()
                .eq("card_id", cardId)
        );
        // 再删除银行卡
        return super.removeById(cardId);
    }
} 